from dataclasses import dataclass
from typing import List, Optional
import datetime

@dataclass
class LsEntry:
    name: str
    size: str 
    size_bytes: int
    month: str
    day: str
    time_or_year: str
    permissions: str
    owner: str
    group: str
    hard_links: int
    base_path: str
    abs_path: str
    link: Optional[str] = None
    modified_time: str = ""
    type: str = ""
    abs_path: str = ""
    sort_key: str = ""


    def __post_init__(self):
        self.type = '目录' if self.permissions[0]=='d' else '文件'
        # 将月份转换为数字
        month_map = {
            'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04',
            'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08',
            'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'
        }
        self.month = month_map[self.month]
        self.day = self.day.zfill(2)
        # 获取当前年份
        current_year = datetime.datetime.now().year
        self.modified_time = f"{current_year}-{self.month}-{self.day}-{self.time_or_year}" if self.time_or_year.count(":") else f"{self.time_or_year}-{self.month}-{self.day}"
        self.sort_key = f"d-{self.name}" if self.permissions[0]=='d' else f"f-{self.name}"


@dataclass
class LsLaOutput:
    total: int
    entries: List[LsEntry]
    bash_path: str = ""

    @classmethod
    def parse(cls,ls_output: str) -> 'LsLaOutput':
        if not ls_output:
            return LsLaOutput(total=0, entries=[])
        lines = ls_output.strip().split('\n')
        base_path = lines[0].strip()
        total = int(lines[1].split()[1])
        entries = []
        for line in lines[2:]:
            # 有些文件名会包含空格，这里假设最多有9列
            parts = line.split(None)
            if len(parts) == 9:
                entry = LsEntry(
                    permissions=parts[0],
                    hard_links=int(parts[1]),
                    owner=parts[2],
                    group=parts[3],
                    size_bytes=int(parts[4]),
                    size=cls.format_file_size(int(parts[4])),
                    month=parts[5],
                    day=parts[6],
                    time_or_year=parts[7],
                    name=parts[8],
                    link=None,
                    base_path=base_path,
                    abs_path=base_path+"/"+parts[8],
                )
                entries.append(entry)
            elif len(parts) == 11:
                entry = LsEntry(
                    permissions=parts[0],
                    hard_links=int(parts[1]),
                    owner=parts[2],
                    group=parts[3],
                    size_bytes=int(parts[4]),
                    size=cls.format_file_size(int(parts[4])),
                    month=parts[5],
                    day=parts[6],
                    time_or_year=parts[7],
                    name=parts[8],
                    link=parts[10],
                    base_path=base_path,
                    abs_path=base_path+"/"+parts[8],
                )
                entries.append(entry)
            else:
                raise ValueError(f"无法解析行: {line}")

        return LsLaOutput(total=total, entries=entries, bash_path=base_path)

    
    @classmethod    
    def format_file_size(cls,size_bytes):
        """格式化文件大小"""
        if size_bytes == 0:
            return "0 B"
        size_names = ["B", "KB", "MB", "GB", "TB"]
        i = 0
        while size_bytes >= 1024 and i < len(size_names) - 1:
            size_bytes /= 1024.0
            i += 1
        return f"{size_bytes:.2f} {size_names[i]}"


    def parse_json(self):
        return {
            "total": self.total,
            "entries": [entry.__dict__ for entry in self.entries],
            "bash_path": self.bash_path
        }
